package com.cloudspace.yunloan.ui.refresh;

import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.cloudspace.yunloan.R;


/**
 * 自定义下拉刷新控件,支持header,footer,emptyview.
 *
 * @author hubaoyu created on 2016-03-17
 */
public class PullToRefreshView extends SwipeRefreshLayout {

    // 列表view
    private RecyclerView mRecyclerView;

    // 根view
    private RelativeLayout mRootRelativeLayout;

    // empty view
    private View mEmptyView;

    // 支持下拉刷新,默认支持
    private boolean mIsSwipeEnable = true;

    // 自动加载回调器
    private LoadMoreListener mLoadMoreListener;

    // 数据适配器
    private AdapterObserver mAdapterObserver;

    private PullToRefreshView.OnScrollListener mOnScrollLinstener;

    private InterOnScrollListener mInterOnScrollListener;

    private PullToRefreshRecyclerViewUtil recyclerViewUtil;

    // 数据源
    private RecyclerView.Adapter mAdapter;

    public PullToRefreshView(Context context) {
        this(context, null);
    }

    public PullToRefreshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setup();
    }

    public synchronized void setOnRefreshComplete() {
        this.setRefreshing(false);
        if (mAdapter != null && mAdapter instanceof RefreshAdapter) {
            RefreshAdapter refreshAdapter = (RefreshAdapter) mAdapter;
            refreshAdapter.setLoadingMore(false);
        }
    }

    public void setLoadMoreListener(PullToRefreshView.LoadMoreListener pagingableListener) {
        mLoadMoreListener = pagingableListener;
    }

    public void setEmptyView(View emptyView) {
        mEmptyView = emptyView;
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
        mRootRelativeLayout.addView(mEmptyView, layoutParams);
        mEmptyView.setVisibility(View.INVISIBLE);
    }

    public void setEmptyView(@LayoutRes int res) {
        try {
            View emptyView = LayoutInflater.from(getContext()).inflate(res, null);
            setEmptyView(emptyView);
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }
        if (mAdapterObserver != null) {
            mAdapterObserver.onChanged();
        }
    }

    public void setEmptyView(String emptyString) {
        View emptyView = LayoutInflater.from(getContext()).inflate(R.layout.empty_layout_white, null);
        TextView mTextView = (TextView) emptyView.findViewById(R.id.empty_tv);
        mTextView.setText(emptyString);
        setEmptyView(emptyView);
        if (mAdapterObserver != null) {
            mAdapterObserver.onChanged();
        }
    }


    public synchronized void setAdapter(RecyclerView.Adapter adapter) {
        if (adapter == null) {
            return;
        }

        if (mAdapter == adapter) {
            adapter.notifyDataSetChanged();
            return;
        }

        if (mAdapter != null) {
            mAdapter.unregisterAdapterDataObserver(mAdapterObserver);
        }

        mAdapter = adapter;
        mRecyclerView.setAdapter(adapter);

        if (mAdapterObserver == null) {
            mAdapterObserver = new AdapterObserver();
        }
        if (adapter != null) {
            adapter.registerAdapterDataObserver(mAdapterObserver);
            mAdapterObserver.onChanged();
        }
    }

    public void addOnScrollListener(PullToRefreshView.OnScrollListener onScrollLinstener) {
        mOnScrollLinstener = onScrollLinstener;
    }

    public RecyclerView.LayoutManager getLayoutManager() {
        if (mRecyclerView != null) {
            return mRecyclerView.getLayoutManager();
        }
        return null;
    }

    public void setSwipeEnable(boolean enable) {
        //just like extra setEnable(boolean).but it's more easy to use, like super.setEnable
        mIsSwipeEnable = enable;
        this.setEnabled(mIsSwipeEnable);
    }

    public boolean isSwipeEnable() {
        return mIsSwipeEnable;
    }

    public RecyclerView getRecyclerView() {
        return this.mRecyclerView;
    }

    public void setLayoutManager(RecyclerView.LayoutManager layoutManager) {
        if (mRecyclerView != null) {
            mRecyclerView.setLayoutManager(layoutManager);
        }
    }

    public void setItemDecoration(RecyclerView.ItemDecoration itemDecoration){
        if(mRecyclerView != null)
            mRecyclerView.addItemDecoration(itemDecoration);
    }

    public int findFirstVisibleItemPosition() {
        return recyclerViewUtil.findFirstVisibleItemPosition(getLayoutManager());
    }

    public int findLastVisibleItemPosition() {
        return recyclerViewUtil.findLastVisibleItemPosition(getLayoutManager());
    }

    public int findFirstCompletelyVisibleItemPosition() {
        return recyclerViewUtil.findFirstCompletelyVisibleItemPosition(getLayoutManager());
    }


    /**
     * main
     */
    private void setup() {
        setupExtra();
        initView();
        setLisenter();
    }

    /**
     * initView
     */
    private void initView() {
        mRootRelativeLayout = (RelativeLayout) LayoutInflater.from(getContext()).inflate(R.layout.refresh_root_view, null);

        this.addView(mRootRelativeLayout);

        this.setColorSchemeResources(R.color.refresh_color0, R.color.refresh_color1);

        mRecyclerView = (RecyclerView) mRootRelativeLayout.findViewById(R.id.recycler_view);

        mRecyclerView.setHasFixedSize(true);

        if (!mIsSwipeEnable) {
            this.setEnabled(false);
        }

    }

    /**
     * Init
     */
    private void setupExtra() {
        recyclerViewUtil = new PullToRefreshRecyclerViewUtil();
    }

    private void setLisenter() {
        mInterOnScrollListener = new InterOnScrollListener();
        mRecyclerView.addOnScrollListener(mInterOnScrollListener);
    }

    /**
     * 获取最后一条展示的位置
     *
     * @return
     */
    private int getLastVisiblePosition() {
        int position;
        if (getLayoutManager() instanceof LinearLayoutManager) {
            position = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
        } else if (getLayoutManager() instanceof GridLayoutManager) {
            position = ((GridLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
        } else if (getLayoutManager() instanceof StaggeredGridLayoutManager) {
            StaggeredGridLayoutManager layoutManager = (StaggeredGridLayoutManager) getLayoutManager();
            int[] lastPositions = layoutManager.findLastVisibleItemPositions(new int[layoutManager.getSpanCount()]);
            position = getMaxPosition(lastPositions);
        } else {
            position = getLayoutManager().getItemCount() - 1;
        }
        return position;
    }

    /**
     * 获得最大的位置
     *
     * @param positions
     * @return
     */
    private int getMaxPosition(int[] positions) {
        int size = positions.length;
        int maxPosition = Integer.MIN_VALUE;
        for (int i = 0; i < size; i++) {
            maxPosition = Math.max(maxPosition, positions[i]);
        }
        return maxPosition;
    }

    private class InterOnScrollListener extends RecyclerView.OnScrollListener {


        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            //do super before callback
            if (mOnScrollLinstener != null) {
                mOnScrollLinstener.onScrollStateChanged(recyclerView, newState);
            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //do super before callback
            if (getLayoutManager() == null) {
                //here layoutManager is null
                return;
            }

            // int firstVisibleItem, visibleItemCount, totalItemCount, lastVisibleItem;
            // visibleItemCount = getLayoutManager().getChildCount();
            // totalItemCount = getLayoutManager().getItemCount();
            // firstVisibleItem = findFirstVisibleItemPosition();
            // // sometimes ,the last item is too big so as that the screen cannot show the item fully
            // lastVisibleItem = findLastVisibleItemPosition();

            if (mIsSwipeEnable) {
                if (findFirstCompletelyVisibleItemPosition() != 0) {
                    //here has a bug, if the item is too big , use findFirstCompletelyVisibleItemPosition will cannot swipe
                    PullToRefreshView.this.setEnabled(false);
                } else {
                    PullToRefreshView.this.setEnabled(true);
                }
            }

            if (mAdapter != null && mAdapter instanceof RefreshAdapter && null != mLoadMoreListener &&
                    ((RefreshAdapter) mAdapter).isFooterEnable() && !((RefreshAdapter) mAdapter).isLoadingMore() && dy > 0) {
                int lastVisiblePosition = getLastVisiblePosition();
                if (lastVisiblePosition + 1 == mAdapter.getItemCount()) {
                    ((RefreshAdapter) mAdapter).setLoadingMore(true);
//                    mLoadMorePosition = lastVisiblePosition;
                    ((RefreshAdapter) mAdapter).setmLoadMorePosition(lastVisiblePosition);
                    mLoadMoreListener.onLoadMore();
                }
            }

            if (mOnScrollLinstener != null) {
                mOnScrollLinstener.onScrolled(recyclerView, dx, dy);
                // mOnScrollLinstener.onScroll(recyclerView, firstVisibleItem, visibleItemCount, totalItemCount);
            }
        }

    }

    /**
     * 数据检测,设置empty view
     */
    private class AdapterObserver extends RecyclerView.AdapterDataObserver {
        @Override
        public void onChanged() {
            //adapter has change
            if (mRecyclerView == null) {
                //here must be wrong ,recyclerView is null????
                return;
            }

            RecyclerView.Adapter<?> adapter = mRecyclerView.getAdapter();
            if (adapter != null && mEmptyView != null) {
                int itemCount;
                if (adapter instanceof RefreshAdapter) {
                    itemCount = ((RefreshAdapter) adapter).getRefreshItemCount();
                } else {
                    itemCount = adapter.getItemCount();
                }
                if (itemCount == 0 && !isRefreshing()) {
                    mEmptyView.setVisibility(View.VISIBLE);
                } else {
                    mEmptyView.setVisibility(View.GONE);
                }
            }
        }
    }

    /**
     * 加载更多监听器,调用者需要实现,并注册.
     */
    public interface LoadMoreListener {
        void onLoadMore();
    }

    /**
     * 滑动检测监听器,调用者需要实现并注册.
     */
    public interface OnScrollListener {
        void onScrollStateChanged(RecyclerView recyclerView, int newState);

        void onScrolled(RecyclerView recyclerView, int dx, int dy);

        //old-method, like listview 's onScroll ,but it's no use ,right ?
        // void onScroll(RecyclerView recyclerView, int firstVisibleItem, int visibleItemCount, int totalItemCount);
    }

}
